package io.github.wslxm.springbootplus2.manage.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.github.wslxm.springbootplus2.client.sys.model.vo.USysDictVO;
import io.github.wslxm.springbootplus2.core.base.model.BasePage;
import io.github.wslxm.springbootplus2.core.base.service.impl.BaseServiceImpl;
import io.github.wslxm.springbootplus2.core.enums.AdminDic;
import io.github.wslxm.springbootplus2.core.enums.BaseDic;
import io.github.wslxm.springbootplus2.core.result.ResultType;
import io.github.wslxm.springbootplus2.core.utils.XjBeanUtil;
import io.github.wslxm.springbootplus2.core.utils.validated.XjValidUtil;
import io.github.wslxm.springbootplus2.manage.sys.dao.SysDictDao;
import io.github.wslxm.springbootplus2.manage.sys.mapper.SysMsgMapper;
import io.github.wslxm.springbootplus2.manage.sys.model.dto.SysMsgDTO;
import io.github.wslxm.springbootplus2.manage.sys.model.entity.SysMsg;
import io.github.wslxm.springbootplus2.manage.sys.model.query.SysMsgQuery;
import io.github.wslxm.springbootplus2.manage.sys.model.vo.SysMsgVO;
import io.github.wslxm.springbootplus2.manage.sys.model.vo.next.SysMsgFindAllNumVO;
import io.github.wslxm.springbootplus2.manage.sys.service.SysMsgService;
import io.github.wslxm.springbootplus2.starter.websocket.model.dto.WebsocketMsgDTO;
import io.github.wslxm.springbootplus2.starter.websocket.service.WebsocketService;
import io.github.wslxm.springbootplus2.utils.JwtUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单-->及时消息通知表
 * <p>
 * ::本代码由[兮家小二]提供的代码生成器生成,如有问题,请手动修改 ::作者CSDN:https://blog.csdn.net/qq_41463655
 * </p>
 *
 * @author wangsong
 * @email 1720696548@qq.com
 * @date 2020-09-23 10:40:23
 */
@Service
public class SysMsgServiceImpl extends BaseServiceImpl<SysMsgMapper, SysMsg> implements SysMsgService {

    @Autowired
    private WebsocketService webSocketService;

    @Autowired
    private SysDictDao sysDictDao;

    @Override
    public BasePage<SysMsgVO> findPage(SysMsgQuery query) {
        if (query.getIsLoginUser() == null) {
            query.setIsLoginUser(true);
        }
        LambdaQueryWrapper<SysMsg> queryWrapper = new LambdaQueryWrapper<SysMsg>()
                .orderByDesc(SysMsg::getCreateTime)
                .eq(query.getIsRead() != null, SysMsg::getIsRead, query.getIsRead())
                .eq(query.getIsLoginUser(), SysMsg::getUserId, JwtUtil.getJwtUser(request).getUserId())
                .in(StringUtils.isNotBlank(query.getMsgTypes()), SysMsg::getMsgType, StringUtils.isNotBlank(query.getMsgTypes()) ? Arrays.asList(query.getMsgTypes().split(",")) : null)
                .notIn(StringUtils.isNotBlank(query.getNoMsgTypes()), SysMsg::getMsgType, StringUtils.isNotBlank(query.getNoMsgTypes()) ? Arrays.asList(query.getNoMsgTypes().split(",")) : null);
        return XjBeanUtil.pageVo(this.page(new Page<>(query.getCurrent(), query.getSize()), queryWrapper), SysMsgVO.class);
    }

    @Override
    public String insert(SysMsgDTO dto) {
        // 根据业务类型获取配置
        USysDictVO msgTypeDict = sysDictDao.findByCodeNext("MSG_TYPE", dto.getMsgType() + "");
        XjValidUtil.isTrue(msgTypeDict == null, ResultType.BASE_NO_RESP_DATA);
        // 获取动态参数
        String paramsStr = "";
        if (dto.getRouteParams() != null && dto.getRouteParams().size() > 0) {
            StringBuilder params = new StringBuilder("");
            Map<String, String> routeParams = dto.getRouteParams();
            for (String key : routeParams.keySet()) {
                params.append("&").append(key).append("=").append(routeParams.get(key));
            }
            paramsStr = params.toString().substring(1);
        }
        // 拼接路由一
        StringBuilder routePath = new StringBuilder("");
        if (StringUtils.isNotEmpty(msgTypeDict.getExt2())) {
            routePath.append(msgTypeDict.getExt2());
        }
        // 拼接路由二
        StringBuilder routePathTwo = new StringBuilder("");
        if (StringUtils.isNotEmpty(msgTypeDict.getExt3())) {
            routePathTwo.append(msgTypeDict.getExt3());
        }
        if (StringUtils.isNotBlank(paramsStr)) {
            routePath.append(routePath.toString().contains("?") ? "&" + paramsStr : "?" + paramsStr);
            routePathTwo.append(routePath.toString().contains("?") ? "&" + paramsStr : "?" + paramsStr);
        }
        // 拼接发送json内容
        Map<String, String> contentMap = new HashMap<>(4);
        // 标题
        contentMap.put("title", msgTypeDict.getExt1());
        // 消息
        contentMap.put("message", dto.getContent());
        // 跳转地址
        contentMap.put("routePath", routePath.toString());
        // 第二跳转地址(可让其 用户pc端使用第一路由 + 用户app端使用第二路由)
        contentMap.put("routePathTwo", routePathTwo.toString());
        // 保存消息
        SysMsg entity = new SysMsg();
        entity.setUserId(dto.getUserId());
        entity.setContent(JSON.toJSONString(contentMap));
        entity.setUserType(dto.getUserType());
        entity.setMsgType(dto.getMsgType());
        entity.setIsRead(BaseDic.Whether.V0.getValue());
        boolean b = this.save(entity);

        // 发送webSocket消息
        boolean isWebsocket = dto.getIsWebsocket() != null && dto.getIsWebsocket();
        if (isWebsocket) {
            WebsocketMsgDTO websocketMsgDTO = new WebsocketMsgDTO();
            websocketMsgDTO.setForm("sys");
            websocketMsgDTO.setUsername("Sys");
            websocketMsgDTO.setTo(dto.getUserId());
            websocketMsgDTO.setContent(JSON.toJSONString(entity));
            //websocketMsgDTO.setExtras(null);
            webSocketService.send(websocketMsgDTO);
        }
        return entity.getId();
    }

    @Override
    public boolean updRead(String id) {
        SysMsg entity = new SysMsg();
        entity.setId(id);
        entity.setIsRead(BaseDic.Whether.V1.getValue());
        return this.updateById(entity);
    }

    @Override
    public boolean updReadByIds(List<String> ids) {
        String userId = JwtUtil.getJwtUser(request).getUserId();
        return this.update(new LambdaUpdateWrapper<SysMsg>()
                .set(SysMsg::getIsRead, BaseDic.Whether.V1.getValue())
                .eq(SysMsg::getIsRead, BaseDic.Whether.V0.getValue())
                .eq(SysMsg::getUserId, userId)
                .in(SysMsg::getId, ids)
        );
    }

    @Override
    public boolean readAll() {
        String userId = JwtUtil.getJwtUser(request).getUserId();
        return this.update(new LambdaUpdateWrapper<SysMsg>()
                .set(SysMsg::getIsRead, BaseDic.Whether.V1.getValue())
                .eq(SysMsg::getIsRead, BaseDic.Whether.V0.getValue())
                .eq(SysMsg::getUserId, userId)
        );
    }



    @Override
    public Long findUnreadNum() {
        return this.count(new LambdaQueryWrapper<SysMsg>()
                .eq(SysMsg::getIsRead, BaseDic.Whether.V0.getValue())
                .eq(SysMsg::getUserId, JwtUtil.getJwtUser(request).getUserId())
        );
    }

    @Override
    public SysMsgFindAllNumVO findAllNum() {
        String userId = JwtUtil.getJwtUser(request).getUserId();
        SysMsgFindAllNumVO vo = new SysMsgFindAllNumVO();
        vo.setAllNum(this.count(new LambdaQueryWrapper<SysMsg>().eq(SysMsg::getUserId, userId)));
        vo.setHaveReadNum(this.count(new LambdaQueryWrapper<SysMsg>().eq(SysMsg::getIsRead, BaseDic.Whether.V1.getValue()).eq(SysMsg::getUserId, userId)));
        vo.setUnreadNum(this.count(new LambdaQueryWrapper<SysMsg>().eq(SysMsg::getIsRead, BaseDic.Whether.V0.getValue()).eq(SysMsg::getUserId, userId)));
        return vo;
    }


    public boolean sendSysUserMsg(String userId, String content) {
        return this.sendSysUserMsg(userId, content, true);
    }

    public boolean sendSysUserMsg(String userId, String content, boolean isWebsocket) {
        return sendSysUserMsg(userId, content, isWebsocket, AdminDic.MsgType.V1.getValue());
    }

    public boolean sendSysUserMsg(String userId, String content, boolean isWebsocket, Integer msgType) {
        return sendSysUserMsg(userId, content, isWebsocket, msgType, null);
    }

    public boolean sendSysUserMsg(String userId, String content, boolean isWebsocket, Integer msgType, Map<String, String> routeParams) {
        // 消息参数
        SysMsgDTO dto = new SysMsgDTO();
        dto.setUserId(userId);
        dto.setContent(content);
        dto.setUserType(AdminDic.MsgUserType.V2.getValue());
        dto.setMsgType(msgType);
        dto.setRouteParams(routeParams);
        dto.setIsWebsocket(isWebsocket);
        // 发送消息
        this.insert(dto);
        return true;
    }


    public boolean sendClientUserMsg(String userId, String content) {
        return sendClientUserMsg(userId, content, 1, null);
    }

    public boolean sendClientUserMsg(String userId, String content, Integer msgType) {
        return sendClientUserMsg(userId, content, msgType, null);
    }

    public boolean sendClientUserMsg(String userId, String content, Integer msgType, Map<String, String> routeParams) {
        // 消息参数
        SysMsgDTO dto = new SysMsgDTO();
        dto.setUserId(userId);
        dto.setContent(content);
        dto.setUserType(AdminDic.MsgUserType.V1.getValue());
        dto.setMsgType(msgType);
        dto.setRouteParams(routeParams);
        dto.setIsWebsocket(false);
        // 发送消息
        this.insert(dto);
        return true;
    }
}
